package com.ttscm.srds.web;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.ttscm.srds.datagram.SeerDataPacket;
import com.ttscm.srds.device.modbus.DeviceHsj;
import com.ttscm.srds.pojo.ResponseResult;
import com.ttscm.srds.pojo.ZflkmTaskStatus;
import com.ttscm.srds.robot.seer.RobotStatus;
import com.ttscm.srds.robot.seer.RobotTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.tinylog.Logger;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.*;

@RestController
@RequestMapping("/nav")
public final class NavigationController {

    @Autowired
    private RobotStatus robotStatus;

    @Autowired
    private RobotTask robotTask;

    @Autowired
    DeviceHsj deviceHsj;

    @GetMapping("/listSite")
    public ResponseResult listSite() throws IOException {
        Logger.info("/nav/listSite");

        List<Map<String, String>> listSite = new ArrayList<>();
        SeerDataPacket dataPacket = robotStatus.stations1301();
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> mapStations1301 = objectMapper.readValue(dataPacket.getBodyDataArea(), new TypeReference<Map<String, Object>>() {
        });
        int resultCode = (int) mapStations1301.get("ret_code");
        if (resultCode != 0) {
            return ResponseResult.fail(resultCode, String.valueOf(mapStations1301.get("err_msg")));
        }
        List<Map<String, Object>> stations = (List<Map<String, Object>>) mapStations1301.get("stations");
        for (int i = 0; i < stations.size(); i++) {
            Map<String, String> mapSite = new HashMap<>();
            mapSite.put("text", String.valueOf(stations.get(i).get("id")));
            mapSite.put("value", String.valueOf(stations.get(i).get("id")));
            listSite.add(mapSite);
        }

        return ResponseResult.succeed(listSite);
    }

    @GetMapping("/execTask/{targetSite}")
    public ResponseResult execTask(@PathVariable("targetSite") String targetSite) throws IOException {
        Logger.info("/nav/execTask");

        if (!StringUtils.hasText(targetSite)) {
            return ResponseResult.fail(99001, "无效的目的站点");
        }
        Logger.info("目的站点：{}", targetSite);

        ObjectMapper objectMapper = new ObjectMapper();

        // 状态查询
        SeerDataPacket dataPacket1020 = robotStatus.taskStatus1020();
        Map<String, Object> resultTaskStatus1020 = objectMapper.readValue(dataPacket1020.getBodyDataArea(), new TypeReference<Map<String, Object>>() {});
        int resultCode = (int) resultTaskStatus1020.get("ret_code");
        if (resultCode != 0) {
            return ResponseResult.fail(resultCode, String.valueOf(resultTaskStatus1020.get("err_msg")));
        }
        int taskStatus = (int) resultTaskStatus1020.get("task_status");
        if (taskStatus == 2) {
            return ResponseResult.fail(100001, "机器人非空闲状态，请稍后执行...");
        }

        // 执行路径导航
        SeerDataPacket dataPacket3051 = robotTask.goTarget3051(null, targetSite);
        Map<String, Object> resultTarget3051 = objectMapper.readValue(dataPacket3051.getBodyDataArea(), new TypeReference<Map<String, Object>>() {
        });
        int resultCodeTarget3051 = (int) resultTarget3051.get("ret_code");
        if (resultCodeTarget3051 != 0) {
            return ResponseResult.fail(resultCode, String.valueOf(resultTarget3051.get("err_msg")));
        }

        return ResponseResult.succeed();
    }

    @GetMapping("/location")
    public ResponseResult location() throws IOException {
        Logger.info("/nav/location");

        ObjectMapper objectMapper = new ObjectMapper();
        SeerDataPacket dataPacket1004 = robotStatus.location1004();
        Map<String, Object> resultLocation1004 = objectMapper.readValue(dataPacket1004.getBodyDataArea(), new TypeReference<Map<String, Object>>() {
        });
        int resultCode = (int) resultLocation1004.get("ret_code");
        if (resultCode != 0) {
            return ResponseResult.fail(resultCode, (String) resultLocation1004.get("err_msg"));
        }
        String currentStation = (String) resultLocation1004.get("current_station");

        return ResponseResult.succeed(currentStation);
    }

    @GetMapping("/taskStatus")
    public ResponseResult taskStatus() throws IOException {
        Logger.info("/nav/taskStatus");

        SeerDataPacket dataPacket1020 = robotStatus.taskStatus1020();
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> resultTaskStatus1020 = objectMapper.readValue(dataPacket1020.getBodyDataArea(), new TypeReference<Map<String, Object>>() {
        });
        int resultCode = (int) resultTaskStatus1020.get("ret_code");
        if (resultCode != 0) {
            return ResponseResult.fail(resultCode, String.valueOf(resultTaskStatus1020.get("err_msg")));
        }

        int taskStatus1 = (int) resultTaskStatus1020.get("task_status");
        String taskStatus2 = "无任务...";
        if (taskStatus1 == 2) {
            //String.format("%03d", new Random().nextInt(10))

            taskStatus2 = "任务执行中...";
        } else if (taskStatus1 == 3) {
            taskStatus2 = "任务挂起中...";
        } else if (taskStatus1 == 4) {
            taskStatus2 = "任务已完成...";
        } else if (taskStatus1 == 5) {
            taskStatus2 = "任务已失败...";
        } else if (taskStatus1 == 6) {
            taskStatus2 = "任务已取消...";
        }
        Map<String, Object> taskStatus = new HashMap<>();
        taskStatus.put("statusCode",taskStatus1);
        taskStatus.put("statusDesc",taskStatus2);

        return ResponseResult.succeed(taskStatus);
    }

    @GetMapping("/zflkm")
    public ResponseResult zflkm() throws IOException {
        Logger.info("/nav/zflkm");

        if (ZflkmTaskStatus.finishedSteps != 0) {
            return ResponseResult.fail(100001, "当前任务未完成，请稍后...");
        }

        ObjectMapper objectMapper = new ObjectMapper();

        // 执行路径导航
        SeerDataPacket dataPacket3051Jack = robotTask.goTarget3051JackLoad(null, "AP13");
        Map<String, Object> result3051JackLoad = objectMapper.readValue(dataPacket3051Jack.getBodyDataArea(), new TypeReference<Map<String, Object>>() {});
        int resultCode3051JackLoad = (int) result3051JackLoad.get("ret_code");
        if (resultCode3051JackLoad != 0) {
            return ResponseResult.fail(resultCode3051JackLoad, String.valueOf(result3051JackLoad.get("err_msg")));
        }
        ZflkmTaskStatus.finishedSteps = 1;
        // TODO 后续任务

        return ResponseResult.succeed();
    }

    @GetMapping("/zflkm2")
    public ResponseResult zflkm2() throws IOException {
        Logger.info("/nav/zflkm2");

        ObjectMapper objectMapper = new ObjectMapper();
        // 执行任务链
        SeerDataPacket dataPacket3106 = robotTask.taskListName3106("TL_20220727191104246B");
        Map<String, Object> result30513106 = objectMapper.readValue(dataPacket3106.getBodyDataArea(), new TypeReference<Map<String, Object>>() {});
        int resultCode3106 = (int) result30513106.get("ret_code");
        if (resultCode3106 != 0) {
            return ResponseResult.fail(resultCode3106, String.valueOf(result30513106.get("err_msg")));
        }
        return ResponseResult.succeed();
    }

    @GetMapping("/sendSignal")
    public ResponseResult sendSignal() throws ModbusProtocolException, UnknownHostException, ModbusNumberException, ModbusIOException {
        Logger.info("/nav/sendSignal");

        deviceHsj.setSignal();

        return ResponseResult.succeed();
    }

    @GetMapping("/readSignal")
    public ResponseResult readSignal() throws ModbusProtocolException, UnknownHostException, ModbusNumberException, ModbusIOException {
        Logger.info("/nav/readSignal");

        int signal = deviceHsj.readSignal();

        return ResponseResult.succeed(signal);
    }

}
